#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include"simple_queue.h"

#define PRODUCER_THREAD_NUM 16
#define CREATE_SQL_NUM 4

char sample[] = {
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122
};

simple_queue* msg_queue = NULL;



char* randInt() {
    // srand(4423);
    int value = (rand()<<17)|(rand()<<2)|(rand()&0x03);
    char* result = (char*)malloc(12);
    sprintf(result, "%d", value);
    return result;
}


int rand_x(unsigned int *nextp)
{
    *nextp = *nextp * 1103515245 + 12345;
    return (unsigned int)(*nextp / 65536) % 32768;
}

char* createSQL() {
    unsigned int seed  = time(NULL)^pthread_self(); 

    int dataLength = (11 + 20 + 50 + 100 + 200 + 300 + 400 + 7) * 4;
    char* pSqls = (char *)malloc(dataLength);

    int vars[][3] = {
         {0, 0, 0},
         {1, 0, 20},
         {1, 0, 50},
         {1, 0, 100},
         {1, 0, 200},
         {1, 0, 300},
         {1, 0, 400}
    };

    int curLen = 0;
    int intStrLen = 0;

    int i = 0;
    for (; i<CREATE_SQL_NUM; i++) {
        int j = 0;
        for (; j < 7; j++) {
            if (vars[j][0] == 0) {
                int value = (rand_x(&seed) << 17) | (rand_x(&seed) << 2) | (rand_x(&seed) & 0x03);
                int n = sprintf(pSqls + curLen, "%d", value);
                curLen += n;
            } else {
                int randStrLen = rand_x(&seed) % vars[j][2];
                int i;
                for (i=0; i<randStrLen; i++) {
                    int pos = rand_x(&seed) % 62;
                    pSqls[curLen] = sample[pos];
                    curLen++;
                }
            }
            if (j != 6) {
                pSqls[curLen] = '|';
                curLen++;
            }
        }
        pSqls[curLen] = '\n';
        curLen++;
    }
    curLen++;
    pSqls[curLen] = '\0';
    return pSqls;
}



void* producerThreadFunc(void* args) {

    // FILE * fp;
    // fp = fopen ("C:\\Users\\49491\\c.txt", "w");
    
    // fp = fopen ("/root/c.txt", "wb");

    int loopTimes = 500000 / PRODUCER_THREAD_NUM / CREATE_SQL_NUM;
    int i = 0;
    for (; i<loopTimes; i++) {
        char *pSql = createSQL();
        push_simple_queue(msg_queue, pSql);
    }
    return NULL;
}

void* consumerThreadFunc(void* args) {
    int loopTimes = 500000 / CREATE_SQL_NUM;
    char* pSQL = NULL;
    int i = 0;
    while (1) {
        // printf("%d", i);
        pop_simple_queue(msg_queue, (void*)&pSQL);

        free(pSQL);

        i++;
        if (i == loopTimes)
            break;
    }
}

int main(void) {
    time_t start,stop;
    start = time(NULL);

    printf("---1-");

    msg_queue = create_simple_queue(100);

    pthread_t threads[PRODUCER_THREAD_NUM];

    for (int i=0; i<PRODUCER_THREAD_NUM; i++) {
        pthread_create(&threads[i], NULL, producerThreadFunc, NULL);
    }
printf("--2--");
    pthread_t threadConsumer;
    pthread_create(&threadConsumer, NULL, consumerThreadFunc, NULL);
printf("---a-");
    pthread_join(threadConsumer, NULL);
printf("---3-");
    for (int i=0; i<PRODUCER_THREAD_NUM; i++) {
        pthread_join(threads[i], NULL);
    }
printf("---4-");
    stop = time(NULL);
    printf("Use Time:%ld\n",(stop-start));
    return 0;
}

